//------------------------------------------------------------------------
//
//	CCGameBox is a game development library for iPhone and iPod Touch.
//
//	Licensed under the BSD license, see LICENSE in root for details.
// 
//	Copyright (c) 2009 James Hui (a.k.a. Dr.Watson)
// 
//	For latest updates, please visit http://www.cocoachina.com
//
//------------------------------------------------------------------------

#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>

#import "EAGLView.h"

#import "CCGameBox.h"
#import "GameApp.h"
#import "Texture2D.h"

#import "MainViewController.h"
#import "WhTSprite.h"


#define USE_DEPTH_BUFFER 1
#define DEGREES_TO_RADIANS(__ANGLE) ((__ANGLE) / 180.0 * M_PI)

// 旋转矩阵
//GLfloat MatrixX[]=
//{1,0,0,0,
//	0,cos(M_PI/15),sin(M_PI/15),0,
//	0,-sin(M_PI/15),cos(M_PI/15),0,
//	0,0,0,1};
//
//GLfloat MatrixXN[]=
//{1,0,0,0,
//	0,cos(M_PI/15),-sin(M_PI/15),0,
//	0,sin(M_PI/15),cos(M_PI/15),0,
//	0,0,0,1};
//
//GLfloat MatrixY[]=
//{cos(M_PI/15),0,-sin(M_PI/15),0,
//	0,1,0,0,
//	sin(M_PI/15),0,cos(M_PI/15),0,
//	0,0,0,1};
//
//GLfloat MatrixYN[]=
//{cos(M_PI/15),0,sin(M_PI/15),0,
//	0,1,0,0,
//	-sin(M_PI/15),0,cos(M_PI/15),0,
//	0,0,0,1};
//
//GLfloat MatrixZ[]=
//{cos(M_PI/15),sin(M_PI/15),0,0,
//	-sin(M_PI/15),cos(M_PI/15),0,0,
//	0,0,1,0,
//	0,0,0,1};
//
//GLfloat MatrixZN[]=
//{cos(M_PI/15),-sin(M_PI/15),0,0,
//	sin(M_PI/15),cos(M_PI/15),0,0,
//	0,0,1,0,
//	0,0,0,1};
//
//GLfloat *Matrix= MatrixYN;



GLfloat Cube[]={-1.0f,1.0f,1.0f,1.0f,
	-1.0f,-1.0f,1.0f,1.0f,
	1.0f,-1.0f,1.0f,1.0f,
	1.0f,1.0f,1.0f,1.0f, // 前表面
	-1.0f,1.0f,1.0f,1.0f,
	-1.0f,1.0f,-1.0f,1.0f,
	-1.0f,-1.0f,-1.0f,1.0f,
	-1.0f,-1.0f,1.0f,1.0f, // 左侧面
	1.0f,1.0f,1.0f,1.0f,
	1.0f,1.0f,-1.0f,1.0f,
	1.0f,-1.0f,-1.0f,1.0f,
	1.0f,-1.0f,1.0f,1.0f, // 右侧面
	1.0f,1.0f,1.0f,1.0f,
	1.0f,1.0f,-1.0f,1.0f,
	-1.0f,1.0f,-1.0f,1.0f,
	-1.0f,1.0f,1.0f,1.0f, // 顶部
	1.0f,-1.0f,-1.0f,1.0f,
	-1.0f,-1.0f,-1.0f,1.0f,
	-1.0f,-1.0f,1.0f,1.0f,
	1.0f,-1.0f,1.0f,1.0f, // 底部
	-1.0f,1.0f,-1.0f,1.0f,
	-1.0f,-1.0f,-1.0f,1.0f,
	1.0f,-1.0f,-1.0f,1.0f,
	1.0f,1.0f,-1.0f,1.0f // 背面
};

//GLfloat CubeNew[96];

#define RENDER_IMAGES 10

GLuint textures[RENDER_IMAGES];
// A class extension to declare private methods
@interface EAGLView ()

@property (nonatomic, retain) EAGLContext *context;
@property (nonatomic, assign) NSTimer *animationTimer;

- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;

@end


@implementation EAGLView

@synthesize context;
@synthesize animationTimer;
@synthesize animationInterval;


// You must implement this
+ (Class)layerClass 
{
	return [CAEAGLLayer class];
}

//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder 
{

	if ((self = [super initWithCoder:coder])) 
	{
		// Get the layer
		CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
		
		eaglLayer.opaque = YES;
		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
		   [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
		
		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
		
		if (!context || ![EAGLContext setCurrentContext:context]) 
		{
			[self release];
			return nil;
		}
		
		animationInterval = 1.0 / 60.0;
		//gameApp = new GameApp();
		//[self setTransform:CGAffineTransformMakeRotation(M_PI/2.0f)];
//		self.frame = CGRectMake(0, 0, 480, 320);
		[self setupView];
		//glGenTextures(10, &textures[0]);
//		Texture2D *tex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
//		textures[0] = [tex name];
		gamebox_ = [[WhTGameBox alloc] init];
	}
	return self;
}


- (void)setupView
{
	//const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;
	const GLfloat			zNear = 0.5,
	zFar = 2000.0,
	fieldOfView = 60.0;
	GLfloat size;
	
	glEnable(GL_DEPTH_TEST);
	glMatrixMode(GL_PROJECTION);
	size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
	
	// This give us the size of the iPhone display
	//CGRect rect = self.bounds;
	CGRect rect = CGRectMake(0, 0, 768, 1024);
	glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);
	//glOrthof(-1.0,                                          // Left
//					 1.0,                                          // Right
//					 -1.0 / (rect.size.width / rect.size.height),   // Bottom
//					 1.0 / (rect.size.width / rect.size.height),   // Top
//					 0.1,                                         // Near
//					 10000.0);                                     // Far
	glMatrixMode(GL_MODELVIEW);
	glViewport(0, 0, rect.size.width, rect.size.height);
	
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

- (void)renderByRotateDirection:(short)direct
{
	//switch (direct) {
//		case 1:
//			Matrix = MatrixX;
//			break;
//		case -1:
//			Matrix = MatrixXN;
//			break;
//		case 2:
//			Matrix = MatrixY;
//			break;
//		case -2:
//			Matrix = MatrixYN;
//			break;
//		case 3:
//			Matrix = MatrixZ;
//			break;
//		case -3:
//			Matrix = MatrixZN;
//			break;
//		default:
//			break;
//	}
//	for(int i=0;i<24;i++)
//	{
//		for (int j=0;j<4;j++)
//		{
//			CubeNew[i*4+j] = Cube[i*4+0]*Matrix[j*4+0]+Cube[i*4+1]*Matrix[j*4+1]+Cube[i*4+2]*Matrix[j*4+2]+Cube[i*4+3]*Matrix[j*4+3];
//		}
//	}
}

- (void)drawView 
{	
	//for(int i=0;i<24;i++)
//	{
//		for (int j=0;j<4;j++)
//		{
//			CubeNew[i*4+j] = Cube[i*4+0]*Matrix[j*4+0]+Cube[i*4+1]*Matrix[j*4+1]+Cube[i*4+2]*Matrix[j*4+2]+Cube[i*4+3]*Matrix[j*4+3];
//		}
//	}
//	
	
	[EAGLContext setCurrentContext:context];    
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	glMatrixMode(GL_MODELVIEW);
	//glClearDepth(1.0); 
	glDepthFunc( GL_LEQUAL ); 
	//glMatrixMode(GL_PROJECTION);
	//glDisable(GL_DEPTH_TEST);
	[gamebox_ render];
	//glTranslatef(-0.1f, 0.f, -0.5f);
	//glBindTexture(GL_TEXTURE_2D, [gamebox_ aac]);
//	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//	glEnable(GL_TEXTURE_2D);
//	
//	
//	glTexCoordPointer(2, GL_SHORT, 0, squareTextureCoords);
//	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//	glLoadIdentity();
//	
//	glPushMatrix();
//	{
//		glTranslatef(0, 0, -2.0);
//		//glRotatef(90, 0.0, 0.0, -3.2);
//		glVertexPointer(4, GL_FLOAT, 0, Cube);
//		glEnableClientState(GL_VERTEX_ARRAY);
//		
//		// Draw the front face in Red
//		//glBindTexture(GL_TEXTURE_2D, textures[0]);
//	//glColor4f(1.0, 0.0, 0.0, 1.0);
//		
//		//glBindTexture(GL_TEXTURE_2D, textures[0]);
//		
//		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//		
//		
//		// Draw the top face in green
//		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//		glDrawArrays(GL_TRIANGLE_FAN, 4, 4);
//		
//		// Draw the rear face in Blue
//	//	glColor4f(0.0, 0.0, 1.0, 1.0);
//		glDrawArrays(GL_TRIANGLE_FAN, 8, 4);
//		
//		// Draw the bottom face
//	//	glColor4f(1.0, 1.0, 0.0, 1.0);
//		glDrawArrays(GL_TRIANGLE_FAN, 12, 4);
//		
//		// Draw the left face
//	//	glColor4f(0.0, 1.0, 1.0, 1.0);
//		glDrawArrays(GL_TRIANGLE_FAN, 16, 4);
//		
//		// Draw the right face
//	//	glColor4f(1.0, 0.0, 1.0, 1.0);
//		glDrawArrays(GL_TRIANGLE_FAN, 20, 4);
//	}
//	glPopMatrix();
	
	//for (int i=0;i<96;i++)
//	{
//		Cube[i] = CubeNew[i];
//	}
	
	
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
}

- (void)layoutSubviews 
{
	[EAGLContext setCurrentContext:context];
	[self destroyFramebuffer];
	[self createFramebuffer];
	
//	CCGameBoxInit();
//
//	gameApp->BeginLayout();
//	killsLb = [[UILabel alloc] initWithFrame:CGRectMake(2, 2, 100, 25)];
//	killsLb.font = [UIFont boldSystemFontOfSize:15];
//	killsLb.textColor = [UIColor whiteColor];
//	killsLb.backgroundColor = [UIColor clearColor];
//	killsLb.text = [NSString stringWithFormat:@"Kills: %d",gameApp->mKills];
//	[self addSubview:killsLb];
//	[killsLb release];
//	
//	healthLb = [[UILabel alloc] initWithFrame:CGRectMake(110, 2, 100, 25)];
//	healthLb.font = [UIFont boldSystemFontOfSize:15];
//	healthLb.textColor = [UIColor whiteColor];
//	healthLb.backgroundColor = [UIColor clearColor];
//	healthLb.text = [NSString stringWithFormat:@"Health: %d",gameApp->mHealth];
//	[self addSubview:healthLb];
//	[healthLb release];
	
	[self drawView];
}


- (BOOL)createFramebuffer 
{
	
	glGenFramebuffersOES(1, &viewFramebuffer);
	glGenRenderbuffersOES(1, &viewRenderbuffer);
	
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
	[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
	
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
	
	if (USE_DEPTH_BUFFER) 
	{
		glGenRenderbuffersOES(1, &depthRenderbuffer);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
		glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
	}

	if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
	{
		NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
		return NO;
	}
	
	return YES;
}


- (void)destroyFramebuffer 
{
	
	glDeleteFramebuffersOES(1, &viewFramebuffer);
	viewFramebuffer = 0;
	glDeleteRenderbuffersOES(1, &viewRenderbuffer);
	viewRenderbuffer = 0;
	
	if(depthRenderbuffer) 
	{
		glDeleteRenderbuffersOES(1, &depthRenderbuffer);
		depthRenderbuffer = 0;
	}
}


- (void)startAnimation 
{
	self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
	mOldTime = CFAbsoluteTimeGetCurrent();
}


- (void)stopAnimation 
{
	self.animationTimer = nil;
}


- (void)setAnimationTimer:(NSTimer *)newTimer 
{
	[animationTimer invalidate];
	animationTimer = newTimer;
}


- (void)setAnimationInterval:(NSTimeInterval)interval 
{
	
	animationInterval = interval;
	if (animationTimer) 
	{
		[self stopAnimation];
		[self startAnimation];
	}
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
	//UITouch *touch = [touches anyObject];
//	
//	CGPoint touchPoint = [touch locationInView:self];
//	
//	if (gameApp)
//		gameApp->TouchesBegan(touchPoint.x,touchPoint.y);
}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
	
	//UITouch *touch = [touches anyObject];
//	
//	CGPoint touchPoint = [touch locationInView:self];
//	
//	if (gameApp)
//		gameApp->TouchesMoved(touchPoint.x,touchPoint.y);
	
	
}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	//UITouch *touch = [touches anyObject];
//		
//	CGPoint touchPoint = [touch locationInView:self];
//	
//	//NSLog(@"%f  %f",touchPoint.x,touchPoint.y);
//	
//	if (gameApp)
//		gameApp->TouchesEnded(touchPoint.x,touchPoint.y);
//		
}

- (void)dealloc 
{	
	[self stopAnimation];
	
	if ([EAGLContext currentContext] == context) 
	{
		[EAGLContext setCurrentContext:nil];
	}
	//delete gameApp;
	
	CCGameBoxDestroy();
	
	[context release];	
	[super dealloc];
}

@end
